package com.xpec.c4.db.util;

import java.math.BigDecimal;

import org.apache.commons.lang3.StringUtils;

import com.xpec.c4.db.cfg.DBConfig;

/**
 * 构造或拆分字符串的工具类
 * 
 * @author zhongzhengkai
 * 
 */
public class CodecTool {

	/**
	 * @param stringBuilder
	 *            欲使用的StringBuilder对象
	 * @param str
	 *            要附加的字符串
	 * @param splitterLevel
	 *            欲使用的分隔符层数
	 */
	public static void append(StringBuilder stringBuilder, String str,
			int splitterLevel) {
		String splitter = DBConfig.splitters.get(splitterLevel).getSplitter();

		if (str == null) {
			stringBuilder.append(splitter);
		} else {
			stringBuilder.append(str).append(splitter);
		}
	}

	/**
	 * @param stringBuilder
	 *            欲使用的StringBuilder对象
	 * @param str
	 *            要附加的字符串
	 */
	public static void append(StringBuilder stringBuilder, String str) {

		if (str == null) {
			stringBuilder.append("");
		} else {
			stringBuilder.append(str);
		}
	}

	/**
	 * @param stringBuilder
	 *            stringBuilder 欲使用的StringBuilder对象
	 * @param str
	 *            要附加的字符串
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder stringBuilder, String str,
			String splitter) {
		if (str == null) {
			stringBuilder.append(splitter);
		} else {
			stringBuilder.append(str).append(splitter);
		}
	}

	/**
	 * 按指定的分隔符分隔字符串，返回字符串数组，分隔符间无字符串的在数组中会设置为null
	 * 
	 * @param str
	 *            要分隔的字符串
	 * @param reChange
	 *            定义的分隔符
	 * @return
	 */
	public static String[] split(String str, String reChange) {
		if (str == null) {
			return null;
		}
		String[] strings = StringUtils.splitPreserveAllTokens(
				str, reChange);
		int len = strings.length;
		for (int i = 0; i < len; i++) {
			if (strings[i].length() == 0) {
				strings[i] = null;
			}
		}
		return strings;
	}


	/**
	 * 
	 * @param stringBuffer
	 *            欲使用的stringBuffer对象
	 * @param string
	 *            要附加的字符串
	 * @param separator
	 *            要附加的分隔符
	 */
	public static void append(StringBuffer stringBuffer, String string,
			String separator) {
		if (string == null) {
			stringBuffer.append(separator);
		} else {
			stringBuffer.append(string).append(separator);
		}
	}

	/**
	 * 将欲附加的布尔型的值转为0或1
	 * 
	 * @param stringBuilder
	 *            欲使用的stringBuffer对象
	 * @param bool
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder stringBuilder, Boolean bool,
			String splitter) {
		if (bool == null) {
			stringBuilder.append(splitter);
		} else if (bool == false) {
			stringBuilder.append(0).append(splitter);
		} else if (bool == true) {
			stringBuilder.append(1).append(splitter);
		}
	}

	/**
	 * 将欲附加的布尔型的值转为0或1
	 * 
	 * @param stringBuilder
	 *            欲使用的stringBuffer对象
	 * @param bool
	 */
	public static void append(StringBuilder stringBuilder, Boolean bool) {
		if (bool == null) {
			stringBuilder.append("");
		} else if (bool == false) {
			stringBuilder.append(0);
		} else if (bool == true) {
			stringBuilder.append(1);
		}
	}

	/**
	 * 将欲附加的枚举型的值转为其下标
	 * 
	 * @param stringBuilder
	 *            欲使用的stringBuffer对象
	 * @param e
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder stringBuilder, Enum<?> e,
			String splitter) {
		if (e != null) {
			int index = e.ordinal();
			stringBuilder.append(index).append(splitter);
		} else {
			stringBuilder.append(splitter);
		}
	}

	/**
	 * 通过下标返回和枚举类返回该枚举类的值
	 * 
	 * @param <T>
	 * @param index
	 * @param clazz
	 * @return
	 */
	public static <T extends Enum<?>> T getEnumValue(int index, Class<T> clazz) {
		return clazz.getEnumConstants()[index];
	}

	/**
	 * 通过下标返回和枚举类返回该枚举类的值
	 * 
	 * @param <T>
	 * @param index
	 * @param clazz
	 * @return
	 */
	public static <T extends Enum<?>> T getEnumValue(String index,
			Class<T> clazz) {
		if (index == null) {
			return null;
		}
		return getEnumValue(Integer.valueOf(index), clazz);
	}

	/**
	 * 将欲附加的float型的值进行精度控制处理
	 * 
	 * @param StringBuilder
	 *            欲使用的StringBuilder对象
	 * @param f
	 * @param scale
	 *            欲保留的小数点后的数字的位数
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder stringBuilder, float f, int scale,
			String splitter) {

		if (String.valueOf(f).equals(Float.NaN)) {
			f = 0;
		}
		stringBuilder.append(roundFloat(f, scale, BigDecimal.ROUND_HALF_UP)).append(
				splitter);
	}

	public static void append(StringBuilder stringBuilder, double d, int scale,
			String splitter) {
		if (String.valueOf(d).equals(Double.NaN)) {
			d = 0;
		}
		stringBuilder.append(roundDouble(d, scale, BigDecimal.ROUND_HALF_UP)).append(
				splitter);
	}

	/**
	 * 将欲附加的float型的值进行精度控制处理
	 * 
	 * @param stringBuilder
	 *            欲使用的stringBuffer对象
	 * @param f
	 * @param scale
	 *            欲保留的小数点后的数字的位数
	 */
	public static void append(StringBuilder stringBuilder, float f, int scale) {

		stringBuilder.append(roundFloat(f, scale, BigDecimal.ROUND_HALF_UP));
	}

	public static void append(StringBuilder stringBuilder, double d, int scale) {

		stringBuilder.append(roundDouble(d, scale, BigDecimal.ROUND_HALF_UP));
	}

	/**
	 * 将0转为false 或者将1转为true 并返回
	 * 
	 * @param str
	 * @return
	 */
	public static boolean getBoolean(String str) {
		int i;
		try {
			i = Integer.valueOf(str);
			if (i == 0) {
				return false;
			} else {
				return true;
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return false;

	}

	/**
	 * 对float数据进行精度控制.
	 * <p>
	 * For example: <br>
	 * float value = 100.345678; <br>
	 * float ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br>
	 * ret为100.3457 <br>
	 * 
	 * @param value
	 *            float数据.
	 * @param scale
	 *            精度位数(保留的小数位数).
	 * @param roundingMode
	 *            精度取值方式. 例如BigDecimal.ROUND_HALF_UP @see BigDecimal
	 * @return 精度计算后的数据.
	 */
	public static float roundFloat(float value, int scale, int roundingMode) {
		BigDecimal bd = new BigDecimal(value);
		bd = bd.setScale(scale, roundingMode);
		float d = bd.floatValue();
		bd = null;
		return d;
	}

	/**
	 * 对double数据进行精度控制.
	 * 
	 * @param value
	 *            double数据.
	 * @param scale
	 *            精度位数(保留的小数位数).
	 * @param roundingMode
	 *            精度取值方式.
	 * @return
	 */
	public static double roundDouble(double value, int scale, int roundingMode) {
		BigDecimal bd = new BigDecimal(value);
		bd = bd.setScale(scale, roundingMode);
		double d = bd.doubleValue();
		bd = null;
		return d;
	}

	/**
	 * @param str
	 *            欲使用的stringBuffer对象
	 * @param num
	 *            要附加的数字
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder str, int num, String separator) {
		str.append(num).append(separator);

	}

	/**
	 * @param str
	 *            欲使用的stringBuffer对象
	 * @param num
	 *            要附加的数字
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder str, long num, String separator) {
		str.append(num).append(separator);
	}
	
	/**
	 * @param str
	 *            欲使用的stringBuffer对象
	 * @param num
	 *            要附加的数字
	 * @param splitter
	 *            要附加的分隔符
	 */
	public static void append(StringBuilder str, BigDecimal num, String separator) {
		str.append(num.toString()).append(separator);
	}
}
